package com.company.nuwa.common.utils;

import com.company.nuwa.common.domain.PrizeDto;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * <p>概率抽奖算法</p>
 *
 * @author Lionel Lee
 * @version 1.0: ProbabilityLotteryAlgorithmUtils.java
 * @date 2022/10/10 17:50
 */
@Slf4j
public class ProbabilityLotteryAlgorithmUtils {

    /**
     * 放大倍数
     */
    private static final int MULRIPLE = 1000000;

    public static Long lottery(List<PrizeDto> prizes) {
        int lastScope = 0;
        // 洗牌，打乱奖品次序
        Collections.shuffle(prizes);
        // 奖品的范围区间
        Map<Long, int[]> prizeScopes = Maps.newHashMapWithExpectedSize(prizes.size());
        for (PrizeDto prize : prizes) {
            Long prizeId = prize.getPrizeId();
            // 划分区间
            int currentScope = (int) (lastScope + prize.getProbability() * MULRIPLE);
            prizeScopes.put(prizeId, new int[] { lastScope + 1, currentScope });
            lastScope = currentScope;
        }
        // 获取1-1000000之间的一个随机数
        int luckyNumber = new Random().nextInt(MULRIPLE) + 1;
        // 查找随机数所在的区间
        if (prizeScopes.isEmpty()) {
            return null;
        }

        Optional<Map.Entry<Long, int[]>> op = prizeScopes.entrySet().stream().filter(entry -> {
            int[] value = entry.getValue();
            return luckyNumber >= value[0] && luckyNumber <= value[1];
        }).findFirst();
        return Objects.nonNull(op) && op.isPresent() ? op.get().getKey() : null;
    }
}
